Adopt microunit for tax-unit reconstruction (scoped, behavior-preserving; part of #113)#114
Merged
Conversation
Add microunit as a dependency and route the reconstruction-from-scratch tax-unit path through microunit.construct_tax_units when the person frame carries microunit's raw CPS input columns (PH_SEQ, A_LINENO, A_MARITL, A_SPOUSE, PEPAR1, PEPAR2, A_EXPRRP). When those columns are absent -- the current production case, since microplex's reconstruction frame collapses relationship_to_head and drops the spouse/parent pointers -- the new USPipeline._build_policyengine_tax_units_via_microunit returns None and the legacy role-flag reconstruction runs unchanged. The authoritative-ID path (#112) is never routed here. Net effect is behavior-preserving on today's data: the delegation stays inert until an upstream change threads CPS columns through to entity construction. microunit IS eCPS's tax-unit engine, so activating the delegation converges microplex's tax units toward eCPS's; any resulting loss movement is an entity-convergence effect and must be interpreted as such, not as a quality win (see #113). Adds tests/pipelines/test_us_microunit_delegation.py (4 passing); ruff clean. Implementation produced by the parallel wire-microunit agent; verified (ruff + delegation tests) and committed here. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
microunit 0.1.0 is now published to PyPI, so drop the pre-PyPI git+https commit pin in favor of a standard version constraint. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…r test - Route microunit's filing_status through _normalize_policyengine_filing_status so the delegated path cannot diverge from the legacy paths if microunit ever changes its spelling/casing (today the vocabularies already match). - Add a regression test feeding rows out of PH_SEQ/A_LINENO order, asserting correct unit/role/filing assignment — locks in microunit's input-row-order contract that the positional TAX_ID mapping relies on. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This was referenced May 30, 2026
Closed
MaxGhenis
added a commit
that referenced
this pull request
May 31, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Adds
microunitas a dependency and introduces a delegation seam in the PolicyEngine tax-unit reconstruction path.USPipeline._build_policyengine_tax_units_via_microunitcallsmicrounit.construct_tax_unitswhen the person frame carries microunit's raw CPS input columns (PH_SEQ,A_LINENO,A_MARITL,A_SPOUSE,PEPAR1,PEPAR2,A_EXPRRP), and returnsNoneotherwise.Part of #113. The us-data side of the same adoption is PolicyEngine/policyengine-us-data#1157.
Scope — what this does and does NOT do
A scoped, behavior-preserving first step, not the full ~1,500-line replacement #113 describes.
microunit @ git+…@d3eccbb) + lockfile._build_policyengine_tax_units_from_role_flags(tried first; falls through to the legacy reconstruction onNone).relationship_to_headinto a 0/1/2/3 coding and drops the spouse/parent pointer columns, so the column guard is never satisfied in production → the delegation always returnsNonetoday. It is inert until a follow-up threads CPS columns through to entity construction.microunitis eCPS's tax-unit construction engine. Activating this delegation (in a later PR, once CPS columns are threaded through) makes microplex's tax units converge toward eCPS's. Any loss movement from that must be read as an entity-convergence effect — not microplex improving — and isolated with a matched-N, symmetric-refit, holdout before/after comparison on the same target surface. This PR deliberately keeps the delegation inert so it can land without touching the live benchmark.Tests
tests/pipelines/test_us_microunit_delegation.py— 4 passing (exercises the real delegation path with a CPS-shaped fixture;microunitinstalled).ruff checkclean on changed files.Reviewer notes
_build_policyengine_tax_units_via_microunit: microunit keys on(PH_SEQ, A_LINENO); per-personTAX_ID/role and per-unitfiling_statusare mapped back onto microplex'sperson_id/household_idwithstart_tax_unit_idoffsetting. Please scrutinize that mapping and the offsetting.🤖 Generated with Claude Code